
"""
This is the explicit class for Subplot.
"""
#Importing built-in python modules and functions
import sys, os
from os import walk
import datetime
import string

import time

import PyQt4#BHC this is for the QtCore.String matching
from PyQt4 import QtCore, QtGui
from dateutil import parser

# Importing pylab stuff
from matplotlib import rc, rcParams, use, interactive
use('Qt4Agg')
import pylab as P
import numpy as N
import scipy as S
from numpy import linalg
from scipy.stats import stats

#the following allows a smooth use of pylab windows with Qt4.2#
from matplotlib.backends import backend_qt4, backend_qt4agg
backend_qt4.qApp = QtGui.qApp

dir='\\dialogs' #your dir here
if os.path.isdir(dir):
    sys.path.append(dir)
    #print sys.path
    
from code import InteractiveInterpreter as Interpreter#bhc added
######################################

#User defined functions, dialogs, etc.
from dialogs import editingTableView
from models import localDataModels, arrayModels, listModels
from io import sheetDataHandler as sdh
from io import hdfIO
from scripting import shell#bhc added
from scripting.scishell import SciShell
from scripting.Python_Highlighter import TextEdit, PythonHighlighter#bhc added
#from plotting.Plot_Widget import Plot_Widget
from plotting.Plot_Setup_Dialog import Define_Plot_Widget
from plotting.plot_scripting import makeLPC
from plotting.plotDataClass import LPC
from matplotlib.lines import Line2D
#import GUI scripts
import ui_SubPlot


class SubPlot(ui_SubPlot.Ui_MainWindow):
    def __init__(self,MainWindow=None):
        self.MainWindow = MainWindow
        self.localVarTypes = [float,int,str,tuple,list,N.ndarray,datetime.date, dict, LPC]#BHC
        self.localVars = localDataModels.dataSpace(self.localVarTypes)
        ui_SubPlot.Ui_MainWindow.setupUi(self,MainWindow)
        
        #self.__updatePlotScripts__()
        self.__addWidgets__()
        self.__additionalVariables__()
        self.__additionalConnections__()
        self.__setMessages__()
        self.__initLocalVars__()
        self.__initContextMenus__()
        self.__loadUserScripts__(self.__scriptDir)
        self.dialog_test = 43.25
        self.topPlot = None#used as a handle to pass values to the most
                            #recently selected plot widget
        
        self.dummy_text()
    
    def __initContextMenus__(self):
        self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.listView.connect(self.listView, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.listViewContext)
        self.SP_Edit.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.SP_Edit.connect(self.SP_Edit, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.scratchPadContext)
        
        #self.tableWidgetContext()

    def scratchPadContext(self, point):
        '''Create a menu for the scratch pad and associated actions'''
        sp_menu = QtGui.QMenu("Menu", self.SP_Edit)
        sp_menu.addAction(self.actionTools)
        sp_menu.exec_(self.SP_Edit.mapToGlobal(point))
        
    def listViewContext(self, point):
        '''Create a menu for the view containing the local variables'''
        ct_menu = QtGui.QMenu("Menu", self.listView)
        index = self.listView.currentIndex()
        if index:
            ct_menu.addAction(self.actionPlotItem)
            ct_menu.addAction(self.actionDelete)
        # Show the context menu.
        ct_menu.addAction(self.actionDeleteAll)
        ct_menu.exec_(self.listView.mapToGlobal(point))
    
    #def tableWidgetContext(self):
        #self.MainWindow.addAction(self.action_Cut)
        #self.MainWindow.addAction(self.action_Paste)
    
    def __deleteItem__(self):
        index = self.listView.currentIndex()
        if index:
            varName = self.localVars.getPubKeys()[index.row()]
            self.localVars.popItem(varName)
    
    def __addWidgets__(self):
        '''adds all of the custom widgets not specified in the .ui file'''
        interpreter = Interpreter(self.localVars.__dict__)
        #shellClass = shell.get_shell_class()
        
        #self.shell = shellClass(interpreter,parent=self.tb_shell)
        self.shell = SciShell(interpreter,parent=self.tb_shell)
        self.shell.setObjectName("shell")
        #Keep in mind that if the ui file was changed you need to change
        #the appropriate layout or splitter below
        self.hboxlayout3.addWidget(self.shell)
        
        self.SP_Edit = TextEdit(self.sp_widget)
        self.highlighter = PythonHighlighter(self.SP_Edit.document())
        self.highlighter1 = PythonHighlighter(self.plot_textEdit.document())
        
        self.SP_Edit.setObjectName("SP_Edit")
        self.vboxlayout1.addWidget(self.SP_Edit)
        
        self.script_name_cb.addItem(QtCore.QString('New Script Name'))
         
    def __initLocalVars__(self):
        '''Initialization of variables
        All of those variables specified below will be avialable to the user
        '''
        self.localVars.setPubTypes(self.localVarTypes)
        self.localVars['__ghost__'] = []
        self.localVars['P'] = P
        self.localVars['N'] = N
        self.localVars['S'] = S
        self.localVars['linalg'] = linalg
        self.localVars['LPC']=LPC
        self.localVars['lineplot'] = self.lineplot
        #The following line could be very dangerous
        self.localVars['LOCALVARS'] = self.localVars
        #Initiated the user script and plot dictionaries
        self.userScratchDict = {}
        self.plotScripts = {}
      
    def __setMessages__(self):
        '''This function is obvious'''
        self.ClearTableText = "Are you sure you want to erase\nthe entire table content?"
        self.ClearAllDataText = "Are you sure you want to erase\nthe entire data set?"
        self.NotEditableText = "Sorry, this data format is not table-editable."
        self.OpenScriptText = "Choose a python script to launch:"
        self.SaveDataText = "Choose a name for the data file to save:"
        self.ScratchSavePrompt = "Choose file name to save the scratch pad:"
        self.OpenDataText = "Choose a data file to open:"
        self.ResetAllDataText = "This operation will reset all your data.\nWould you like to continue?"

    def __additionalVariables__(self):
        '''Extra variables that are utilized by other functions'''
        self.types = ["float","int","str","date"]#BHC added str
        self.varID = 1
        
        self.varModel = localDataModels.localDataModel(self.localVars)
        self.listView.setModel(self.varModel)
        self.__curDir = os.getcwd()
        self.__scriptDir = 'user_scripts'
        self.__scriptDirPath = '/'.join([self.__curDir,self.__scriptDir])
        self.localForms = None
        self.editTable = None
        self.curFileName = None
        
        self.topPlot = None
        
    def __additionalConnections__(self):
        '''File menu actions slots'''
        QtCore.QObject.connect(self.action_Open,QtCore.SIGNAL("triggered()"),self.__readDataFile__)
        QtCore.QObject.connect(self.action_Save,QtCore.SIGNAL("triggered()"),self.__saveDataFile__)
        QtCore.QObject.connect(self.actionSave_As,QtCore.SIGNAL("triggered()"),self.__saveDataFileAs__)
        QtCore.QObject.connect(self.action_New,QtCore.SIGNAL("triggered()"),self.__newSheet__)
        QtCore.QObject.connect(self.action_Table_Selection,QtCore.SIGNAL("triggered()"),self.__getTableSelection__)
        
        QtCore.QObject.connect(self.action_Cut,QtCore.SIGNAL("triggered()"),self.tableWidget.copyCells)
        QtCore.QObject.connect(self.action_Paste,QtCore.SIGNAL("triggered()"),self.tableWidget.pasteClip)
        
        # Tools actions slots
        QtCore.QObject.connect(self.actionFileOpen,QtCore.SIGNAL("triggered()"),self.__readDataFile__)
        QtCore.QObject.connect(self.actionFileSave,QtCore.SIGNAL("triggered()"),self.__saveDataFile__)
        QtCore.QObject.connect(self.actionFileSaveAs,QtCore.SIGNAL("triggered()"),self.__saveDataFileAs__)
        QtCore.QObject.connect(self.actionNewFile,QtCore.SIGNAL("triggered()"),self.__newSheet__)
        QtCore.QObject.connect(self.action_getSelection,QtCore.SIGNAL("triggered()"),self.__getTableSelection__)
        QtCore.QObject.connect(self.actionTools,QtCore.SIGNAL("triggered()"),self.__runScratchScript__)
        QtCore.QObject.connect(self.actionPlot,QtCore.SIGNAL("triggered()"),self.__definePlot__)
        
        
        
        
        QtCore.QObject.connect(self.actionPlotItem,QtCore.SIGNAL("triggered()"),  self.__plotListItem__)
        
        QtCore.QObject.connect(self.actionAbout,QtCore.SIGNAL("triggered()"),self.__showAbout__)
        QtCore.QObject.connect(self.actionClear,QtCore.SIGNAL("triggered()"),self.__clearTable__)
        QtCore.QObject.connect(self.actionDelete,QtCore.SIGNAL("triggered()"),self.__deleteItem__)
        QtCore.QObject.connect(self.actionDeleteAll,QtCore.SIGNAL("triggered()"),self.__newSheet__)
        # Other slots
        QtCore.QObject.connect(self.shell,QtCore.SIGNAL("shellNewLine"),self.__updateListView__)
        QtCore.QObject.connect(self.listView,QtCore.SIGNAL("doubleClicked(QModelIndex)"),self.__editLocalData__)
        QtCore.QObject.connect(self.listView,QtCore.SIGNAL("clicked(QModelIndex)"), self.__previewItem__)
        QtCore.QObject.connect(self.actionRunScript,QtCore.SIGNAL("triggered()"),self.__executeScript__)
        QtCore.QObject.connect(self.cb_arrayStats, QtCore.SIGNAL("stateChanged(int)"), self.__arrayStats__)
        QtCore.QObject.connect(self.btn_saveScript, QtCore.SIGNAL("clicked()"), self.__saveSP2Disk__)
        QtCore.QObject.connect(self.btn_scratch2Mem, QtCore.SIGNAL("clicked()"), self.__saveSP2Mem__)
        QtCore.QObject.connect(self.script_name_cb, QtCore.SIGNAL("currentIndexChanged(QString)"), self.__scratchComboAction__)
        #QtCore.QObject.connect(self.script_name_cb, QtCore.SIGNAL("editTextChanged(QString)"), self.__scratchNameChange__)
        QtCore.QObject.connect(self.cb_plotScriptName, QtCore.SIGNAL("currentIndexChanged(QString)"), self.__plotScriptAction__)
        QtCore.QObject.connect(self.btn_executePlot,QtCore.SIGNAL("clicked()"),self.__runPlotScript__)
        
        QtCore.QMetaObject.connectSlotsByName(self.MainWindow)
    
    def __scratchComboAction__(self, entry):
        #print "Combo Index"
        if entry and self.userScratchDict.has_key(entry):# is not self.script_name_cb.currentText():            
            self.SP_Edit.setPlainText(self.userScratchDict.get(entry))#self.script_name_cb.currentText()))
    
    def __updatePlotScripts__(self):
        self.cb_plotScriptName.clear()
        self.cb_plotScriptName.addItems(self.plotScripts.keys())
    
    def __updateScratchScripts__(self):
        self.script_name_cb.clear()
        self.script_name_cb.addItems(self.userScratchDict.keys())
    
    def __plotScriptAction__(self, entry):
        if entry and self.plotScripts.has_key(str(entry)):
            self.plot_textEdit.setPlainText(self.plotScripts.get(str(entry))[0])
    
    def __plotListItem__(self):
        index = self.listView.currentIndex()
        if index.isValid():
            varName = self.localVars.getPubKeys()[index.row()]
            data2plot = self.localVars[varName]
            if type(data2plot) is N.ndarray:
               if len(N.shape(data2plot)) is 1:
                   self.lineplot(data2plot,  ylabel = varName)
        
        
    def __arrayStats__(self, state):
        '''a state of 2 is checked, if so then the array stats are calculated
        for that particular array and passed to the TextEdit'''
        if int(state) is 2:
            index = self.listView.currentIndex()
            if index.isValid():
                varName = self.localVars.getPubKeys()[index.row()]
                item = self.localVars[varName]
                self.te_arrayStats.clear()
                if type(item) is N.ndarray:
                    if item.ndim is 1:
                        stat_type = ['Length', 'Mean', 'Median', 'Std Dev', 'Sum Sqr']
                        stats_list = []
                        stats_list.append(len(item))
                        stats_list.append(stats.mean(item))
                        stats_list.append(stats.median(item))
                        stats_list.append(stats.std(item))
                        stats_list.append(stats.square_of_sums(item))                        
                        
                        
                        #need to add a validator for 1-D Arrays
                        for index in range(len(stat_type)):
                            current_stat = ':'.join([stat_type[index], str(stats_list[index])])
                            self.te_arrayStats.append(current_stat)
        
    
    def __loadUserScripts__(self, directory):
        '''This function loads all of the python files in the "user_scripts"
        directory.  This is not perfect as the scripts are passed
        to the intepreter so that the variables and functions in those files
        can be accessed from the command line.  If there is an error in a 
        file the program will still contintue.'''
        mod_dict = {}#module dictionary
        for root, dirs, files in walk(directory):#leaving roots and dirs there for future use
            for file in files:
                if '.py' in file and '.pyc' not in file:
                    if '__init__.py' not in file and '__init__.pyc' not in file:
                        modname = file.split('.')[0]#module name
                        modpath = '.'.join([directory,modname])#module path
                        mod_dict[modname]=modpath
        for item in mod_dict.items():
            try:
                import_string = 'import %s as %s\r' % (item[1], item[0])
                self.shell.fakeUser([import_string])
                self.shell.setFocus()
                    
            except ImportError:
                print "Error importing %s"%item[0]    
    
    def __previewItem__(self, index):
        '''If the item selected is a numpy array then then then a graph
        of the item will be displayed in the plotPreview widget'''
        
        self.localVars['ax'] = self.topPlot
        
        
        varName = self.localVars.getPubKeys()[index.row()]
        data2Preview = self.localVars[varName]
        if type(data2Preview) is N.ndarray:
            if len(N.shape(data2Preview)) is 1:
                self.plotPreview.canvas.ax.plot(data2Preview)
                self.__arrayStats__(self.cb_arrayStats.checkState())
            if len(N.shape(data2Preview)) > 1:
                self.plotPreview.canvas.ax.pcolor(data2Preview)
                
            self.plotPreview.canvas.update_plot()
        else:#not a numpy array so the plot and array stats are cleared
            self.te_arrayStats.clear()
            self.plotPreview.canvas.ax.cla()
            self.plotPreview.canvas.update_plot()
            #self.plotPreview.canvas.draw()
    
    def __definePlot__(self):
        '''Opens a dialog to define the a 2D plot'''
        localArrayList = []
        
        vars = self.localVars.getPubDict()
        #print vars
        for key in vars.iterkeys():
            if type(vars.get(key)) is N.ndarray and len(N.shape(vars.get(key))) is 1:
                localArrayList.append(key)
        localArrayList.sort()
        self.plot_setup = Define_Plot_Widget(localArrayList, vars, False, self)
        self.plot_setup.show()
    
    def __plotDialog__(self):
        #print "plotDialog triggered"
        vars = self.localVars.getPubDict()
    
    def __localDataReset__(self):
        self.tableWidget.clear()
        self.localVars.clear()
        self.__initLocalVars__()
        self.userScratchDict = {}
        self.plotScripts = {}
        self.__updatePlotScripts__()

    def __askConfirm__(self,title,message):
        clickedButton = QtGui.QMessageBox.question(self.MainWindow,\
                                                   title,message,\
                                                   QtGui.QMessageBox.Yes,QtGui.QMessageBox.Cancel)
        if clickedButton == QtGui.QMessageBox.Yes: return True
        return False
        
    def __newSheet__(self):
        if self.__askConfirm__("Data Clear",self.ClearAllDataText):
            return self.__localDataReset__()
    

    def __readDataFile__(self):
        if self.__askConfirm__("Data Reset",self.ResetAllDataText):
            dataFileName = QtGui.QFileDialog.getOpenFileName(self.MainWindow,\
                                                             self.OpenDataText,\
                                                             self.__curDir, 'SubPlot File (*.spf);;HDF5 File (*.h5)')
                                                             
            if dataFileName:
                # dataFileName
                self.__localDataReset__()
                varDict,  self.userScratchDict,  self.plotScripts = hdfIO.load_workspace(str(dataFileName))
                self.__updatePlotScripts__()
                self.__updateScratchScripts__()
                for item in varDict.iteritems():
                    self.localVars[item[0]] = item[1]
                return self.__updateListView__()
    
    def __saveDataFile__(self):
        self.curFileName = QtGui.QFileDialog.getSaveFileName(self.MainWindow,\
                                                             self.SaveDataText,\
                                                             self.__curDir, 'SubPlot File (*.spf);;HDF5 File (*.h5)')
        if self.curFileName:
            #print "File name is: %s" % (str(self.curFileName))
            hdfIO.save_workspace(str(self.curFileName),  self.localVars.getPubDict(),  self.userScratchDict,  self.plotScripts)
    
    def __saveDataFileAs__(self):
        dataFileName = QtGui.QFileDialog.getSaveFileName(self.MainWindow,\
                                                         self.SaveDataText,\
                                                         self.__curDir,'Pqs data (*.pqs)')
        if dataFileName:
            print dataFileName
            print "Currently this function does not do anything"



    def __scratchNameChange__(self, entry):
        print entry
        
    def __saveSP2Mem__(self):
        if self.script_name_cb.currentText():
            print '\nScratch Pad saved as %s'%(self.script_name_cb.currentText())
#            if self.userScratchDict.has_key(self.script_name_cb.currentText()):
#                #print "Key exists"
#                pass#not sure this does what I think it is
#            else:
#                #print "Key does not exist"
#                self.script_name_cb.addItem(self.script_name_cb.currentText())#add script name to the combo box for future access

            self.userScratchDict[self.script_name_cb.currentText()] = self.SP_Edit.document().toPlainText()
            self.__updateScratchScripts__()

            
        else:
            return QtGui.QMessageBox.warning(self.MainWindow,\
                                                 "That action is Verbotten",\
                                                 "You need to enter a script name first!",\
                                                 QtGui.QMessageBox.Ok)
        
    def __saveSP2Disk__(self):
        if self.script_name_cb.currentText():
            
            spFilePath = '/'.join([self.__scriptDirPath, str(self.script_name_cb.currentText())])
        else:
            spFilePath = '/'.join([self.__scriptDirPath,''])
        
        dataFileName = QtGui.QFileDialog.getSaveFileName(self.MainWindow,\
                                                 self.ScratchSavePrompt,\
                                                 spFilePath,'Python File (*.py)')
        if dataFileName:
            scratch_text = self.SP_Edit.document().toPlainText()
            #lines = unicode((script_text.toPlainText()).splitlines(True))
            try:
                if os.path.isfile(dataFileName):
                    fout = open(dataFileName, 'a')
                    fout.write(scratch_text)
                    fout.close()
                    print "Scratch Pad appended to: %s"%(dataFileName)
                else:
                    fout = open(dataFileName, 'w')
                    fout.write(scratch_text)
                    fout.close()
                    print "Scratch Pad written to: %s"%(dataFileName)
            except:
                print "Error writing scratch pad to file."
            
            finally:
                    self.userScratchDict[self.script_name_cb.currentText()]=scratch_text

    def __buildDataModel__(self,data2Show, dataType):
        #dataType = type(data2Show)
        if dataType is N.ndarray:
            #editableModel = listModels.generalListModel()
            #editableModel.setTheList(data2Show)
            editableModel = arrayModels.numericArrayModel()
            editableModel.setTheArray(data2Show)
            return editableModel
        elif dataType is list:
            editableModel = listModels.generalListModel()
            editableModel.setTheList(data2Show)
            return editableModel
        else:
            raise Exception(self.NotEditableText)
    
    def __editLocalData__(self,index):
        varName = self.localVars.getPubKeys()[index.row()]
        data2Show = self.localVars[varName]
        dataType = type(data2Show)
        #print "Variable name: ", varName
        if index.isValid():
            try:
                if dataType is PyQt4.QtCore.QString:#BHC
                    data2Show=str(data2Show)#BHC
                    value, ok = QtGui.QInputDialog.getText(self.MainWindow, 'Change Variable Value',\
                    'Enter new value: ', QtGui.QLineEdit.Normal, data2Show)
                    if ok:
                        self.localVars[varName] = str(value)
                
                elif dataType is str:#BHC
                    #print "Variable is a string"#BHC
                    value, ok = QtGui.QInputDialog.getText(self.MainWindow, 'Change Variable Value',\
                    'Enter new value: ', QtGui.QLineEdit.Normal, data2Show)
                    if ok:
                        self.localVars[varName] = str(value)

                elif dataType is int:#BHC
                    #print "Variable is an int"#BHC
                    value, ok = QtGui.QInputDialog.getInteger(self.MainWindow, 'Change Variable Value',\
                    'Enter new value: ', data2Show, -2147483647, 2147483647, 1)
                    if ok:
                        self.localVars[varName] = value
                        
                elif dataType is float:#BHC
                    #print "Variable is a float"
                    value, ok = QtGui.QInputDialog.getDouble(self.MainWindow, 'Change Variable Value',\
                    'Enter new value: ', data2Show, -2147483647, 2147483647, len(data2Show.__str__()))
                    if ok:
                        self.localVars[varName] = value
                        
                else:
                    "List or Numpy Array"
                    self.localForms = QtGui.QWidget()
                    self.editableModel = self.__buildDataModel__(data2Show, dataType)
                    self.editTable = editingTableView.Ui_Form()
                    self.editTable.setupUi(self.localForms,self.editableModel,"Editing: '%s'" % varName)
                    return self.localForms.show()
                
            except Exception, instance:
                return QtGui.QMessageBox.warning(self.MainWindow,\
                                                 "Information",\
                                                 instance.message,\
                                                 QtGui.QMessageBox.Ok)

    def __readAndConverItem__(self,newVarType,row,col):
        if (newVarType == ''):
            return self.tableWidget.item(row,col).text().to()[0]
        elif (newVarType == 'int'):
            return self.tableWidget.item(row,col).text().toInt()[0]
        elif (newVarType == 'float'):#BHC
            return self.tableWidget.item(row,col).text().toFloat()[0]#BHC
        elif (newVarType == 'str'):#BHC
            return str(self.tableWidget.item(row,col).text()[0:])#BHC
        elif (newVarType == 'date'):
            return parser.parse(self.tableWidget.item(row,col).text().__str__(),dayfirst=True).date()

    def __setHorizList__(self,newVarName,newVarType,row,leftCol,rightCol):
        self.localVars[newVarName] = []
        for i in range(leftCol,rightCol+1):
            self.localVars[newVarName].append(self.__readAndConverItem__(newVarType,row,i))


    def __getTableList__(self,newVarType):
        t1 = time.time()
        ############################
        tmpVar = []
        tmpList = self.tableWidget.selectedItems()
        if (newVarType == ''):
            return item.text()[0]
        elif (newVarType == 'int'):
            for item in tmpList:
                tmpVar.append(item.text().toInt()[0])#[0] is used to get just the number not the bool
            return N.array(tmpVar)
        elif (newVarType == 'float'):#BHC
            for item in tmpList:
                tmpVar.append(item.text().toFloat()[0])
            return N.array(tmpVar)
        elif (newVarType == 'str'):#BHC
            for item in tmpList:
                tmpVar.append(str(item.text()[0:]))
            return tmpVar
        elif (newVarType == 'date'):
            for item in tmpList:
                tmpVar.append(parser.parse(item.text().__str__(),dayfirst=True).date())
            return tmpVar

        print (time.time()-t1)
    
    def __setVertList__(self,newVarName,newVarType,upRow,downRow,col):
        t1 = time.time()
#        self.localVars[newVarName] = []
#        for i in range(upRow,downRow+1):
#            self.localVars[newVarName].append(self.__readAndConverItem__(newVarType,i,col))
        ############################
        tmpVar = []
        tmpList = self.tableWidget.selectedItems()
        
        if (newVarType == ''):
            return self.tableWidget.item(row,col).text().to()[0]
        elif (newVarType == 'int'):
            for item in tmpList:
                tmpVar.append(item.text().toInt()[0])#[0] is used to get just the number not the bool
            return tmpVar
        elif (newVarType == 'float'):#BHC
            for item in tmpList:
                tmpVar.append(item.text().toFloat()[0])
            return tmpVar
        
        elif (newVarType == 'str'):#BHC
            for item in tmpList:
                tmpVar.append(item.text()[0:])
            return tmpVar
        elif (newVarType == 'date'):
            for item in tmpList:
                tmpVar.append(parser.parse(item.text().__str__(),dayfirst=True).date())
            return tmpVar

        #self.localVars[newVarName] = N.array(tmpVar)
        print (time.time()-t1)
  
    def __showAbout__(self):
        return QtGui.QMessageBox.information(self.MainWindow,
                                            ("SubPlot V.0.1, June, 2008"),
                                            ("<p>Based upon the program <b>pqsheet</b> originally coded by"
        " Alex Rada (alex_radi@yahoo.it), <b>Subplot</b> is a modification"
        " and expansion by Brian H. Clowers (bhclowers@gmail.com).</p>"
        "<p>Please keep in mind that the entire effort is very much a"
        " work in progress and that Brian won't quit his day job for programming."
        " The original purpose of SubPlot was to provide a rapid, open-source tool"
        " for examining scientific data and provide the hooks necessary to access"
        " the scipy, numpy, and matplotlib libraries.  Feel free to update"
        " (preferably with documentation) SubPlot and please share your contributions"
        " with the rest of the community.</p>"))
  
    def __updateListView__(self):
        self.varModel.reload()
  
    def __setArray__(self,newVarName,newVarType,upRow,downRow,leftCol,rightCol):
        self.localVars[newVarName] = []
        for i in range(upRow,downRow+1):
            tmpVar = []
            for j in range(leftCol,rightCol+1):
                tmpVar.append(self.__readAndConverItem__(newVarType,i,j))
            self.localVars[newVarName].append(tmpVar)
  
    def __clearTable__(self):
        if self.__askConfirm__("Table Clear",self.ClearTableText):
            self.tableWidget.clear()
  
    def __getTableSelection__(self):
        newVarName, newVarType = '', ''
        inputDiagOut1 = QtGui.QInputDialog.getItem(self.MainWindow,\
                                                   "New variable type","Choose variable type:",self.types, 0, False)
        newVarType=str(inputDiagOut1[0])
        if newVarType == "int" or newVarType == "float":
            newVarName = "%s%d" % ("wave", self.varID)
        else:
            newVarName = "%s%d" % (newVarType, self.varID)
        self.varID+=1
    
        if inputDiagOut1[1]:
            inputDiagOut2 = QtGui.QInputDialog.getText(self.MainWindow,\
                                                   "New variable name","Insert variable name:", QtGui.QLineEdit.Normal, QtCore.QString(newVarName))
        else:
            return 0

        newVarName = str(inputDiagOut2[0])
        
        # If fields are not empty
        if newVarName and newVarType:
            selRanges = self.tableWidget.selectedRanges()
            upRow, downRow, leftCol, rightCol = \
                    selRanges[0].topRow(), selRanges[0].bottomRow(),\
                    selRanges[0].leftColumn(), selRanges[0].rightColumn()
            nRows, nCols = downRow-upRow+1, rightCol-leftCol+1
            if nRows > 1 and nCols > 1:
                self.__setArray__(newVarName,newVarType,upRow,downRow,leftCol,rightCol)
            elif nRows > 1 and nCols == 1:
                self.localVars[newVarName] = self.__getTableList__(newVarType)
                #self.__setVertList__(newVarName,newVarType,upRow,downRow,leftCol)
            elif nCols > 1 and nRows == 1:
                self.localVars[newVarName] = self.__getTableList__(newVarType)
                #self.__setHorizList__(newVarName,newVarType,upRow,leftCol,rightCol)
            else:
                self.localVars[newVarName] = self.__readAndConverItem__(newVarType,upRow,leftCol)
        return self.__updateListView__()

    def __executeScript__(self):
        scriptName = QtGui.QFileDialog.getOpenFileName(self.MainWindow,\
                                                       self.OpenScriptText,\
                                                       self.__curDir,'Python (*.py)')
        if scriptName:
            scriptIn = file(scriptName,'r')
            scriptLines = scriptIn.readlines()
            scriptIn.close()
            return self.shell.fakeUser(scriptLines)
    
    def __runScratchScript__(self):
        '''script_text is of type QDocument which must be changed to
        unicode before the splitlines operation may be used.  The TRUE
        at the end of this command keeps the end of line character intact
        so the fakeUser command can add the text to the shell properly'''
        script_text = self.SP_Edit.document()
        lines = unicode(script_text.toPlainText()).splitlines(True)
        self.shell.setFocus()
        self.scripts_tabWidget.setCurrentIndex(0)
        print type(lines)
        print lines
        return self.shell.fakeUser(lines)
    
    def __runPlotScript__(self):
        script_text = self.plot_textEdit.document()
        lines = unicode(script_text.toPlainText()).splitlines(True)
        self.shell.setFocus()
        self.scripts_tabWidget.setCurrentIndex(0)
        return self.shell.fakeUser(lines)
    
        
    def getVar(self,varName):
        return self.localVars[varName]

    def dummy_text(self):
        dummy_script = 'x = N.arange(0,20, N.random.random())\r\
y = N.cos(x-N.random.random())\r\
y2 = 2*N.cos(x-N.random.random())\r\
y3 = 2*N.sin(x-N.random.random())\r\
Z = N.arange(10000.0); Z.shape = 100,100\r\
Z[:,50:] = 1\r\
String = "yahoo"\r\
Float = 3.3241\r\
ShortList = [3,2,6,4,1,3,9]\r\
a,b,c = S.rand(3, 15)\r\
xdict = {"x":x}\r\
ydict = {"y":y, "y2":y2, "y3":y3}\r\
data2plot = LPC([xdict,ydict])\r'
                        
        self.SP_Edit.setText(dummy_script)


    def lineplot(self, x = None,  y=None,     #I added this to the main GUI because I needed access to the localVars.getPubDict() in order to plot
                xlabel = 'x',             # a more elegant way would be nice, but this works for now.
                ylabel = 'y',
                xerr = None, 
                yerr = None, 
                color = None,
                mcolor = None, 
                linestyle = None,
                linewidth = None,
                marker = None,
                markersize = None,
                plotTitle = '',
                range_x = (None, None),
                range_y = (None, None),
                x_axlabel = 'X-Axis',
                y_axlabel = 'Y-Axis',
                logx = False, 
                logy = False, 
                grids = False, 
                DATALIST = None):
                    
        from plotting.Plot_Widget_Line2D import Plot_Widget    
        if x != None or y != None:
            new_LPC = LPC()
            if x != None and y!=None:
                new_LPC.data = Line2D(x, y)
                new_LPC.data.set_picker(5)
            elif x!=None and y == None:
                calcx = N.arange(0,len(x))
                new_LPC.data = Line2D(calcx, x)
                new_LPC.data.set_picker(5)
            
            new_LPC.xlabel = xlabel
            new_LPC.ylabel = ylabel
            
            if xerr:
                new_LPC.set_xerr(xerr,  xerr)
                
            if yerr:
                new_LPC.set_yerr(yerr,  yerr)   
                
            
            if markersize:
                new_LPC.data.set_markersize(markersize)
            if marker:
                new_LPC.data.set_marker(marker)
            if linewidth:
                new_LPC.data.set_linewidth(linewidth)
            if linestyle:
                new_LPC.data.set_linestyle(linestyle)
            if color:
                new_LPC.data.set_color(color)
            if mcolor:
                new_LPC.data.set_markerfacecolor(mcolor)
        
        plot = Plot_Widget(parent = self)
        try:
            if new_LPC:# I'm doing this because I don't have a good way to test whether the LPC was created.
                plot.initialize_plot(new_LPC)
        except:
            pass
            

        
        if DATALIST:
            varDict = self.localVars.getPubDict()
            #print varDict
            for line in DATALIST:
                #print "DataList Go"
                #print line
                #print makeLPC(line, varDict)
                plot.initialize_plot(makeLPC(line, varDict))
                
                
        if type(range_x) is tuple:
            plot.xscale = range_x
        elif type(range_x) is not tuple or None:
            print "range_x must be a tuple of min and max axis values"
        
        if type(range_y) is tuple:
            plot.yscale = range_y
        elif type(range_y) is not tuple or None:
            print "range_y must be a tuple of min and max axis values"
            
        plot.grids = grids
        plot.plotTitle = plotTitle
        plot.xtitle = x_axlabel
        plot.ytitle = y_axlabel
        
        plot.updatePlot()
        plot.show()
